其他
两万字总结《C++ Primer》要点
The following article is from Jacen的技术笔记 Author Jacen
对于想要入门C++的同学来说,《C++ Primer》是一本不能错过的入门书籍,它用平易近人的实例化教学激发学生的学习兴趣,帮助学生一步步走进C++的大门。在本文中,作者Jacen用两万多字总结了《C++ Primer 中文版(第五版)》1-16章的阅读要点,可以作为该书的阅读参考。注:原书更为详细,本文仅作学习交流使用。
第一章 开始
1.1 编写一个简单的C++程序
int main()
{
return 0;
}
1.2 初识输入输出
对象 | 用途 |
1.3 注释简介
1.4 控制流
基本内置类型
1.算术类型
类型 | 最小尺寸 |
2.类型转换
变量
1.变量定义
2.变量声明和定义的关系
int j; // 声明并定义j
3.名字的作用域
复合类型
定义:复合类型是基于其他类型定义的类型。
1.引用
2.指针
3.理解复合类型的声明
const限定符
处理类型
类型别名
typedef wages *p; // p是double*的同义词
自定义数据结构
#define SALES_DATA_H
#endif
术语
命名空间的 using 声明
标准库类型 string
using namespace std;
sting s2(s1);
string s3("value");
string s3 = "value";
string s4(n, 'c');
s.size(); // 字符个数
s[n]; // s中第n个字符的引用
s1+s2; // s1和s2连接
<,<=,>,>= // 比较
statement
标准库类型 vector
vector<T> v2(v1);
vector<T> v2 = v1;
vector<T> v3(n, val);
vector<T> v4(n);
vector<T> v5{a,b,c...}
vecrot<T> v5={a,b,c...}
v.size();
v.push_back(t);
v[n];
迭代器介绍
iter->mem // 等价于 (*iter).mem
++iter
--iter
iter1 == iter2
iter1 != iter2
iter + n
iter - n
iter += n
iter -= n
iter1 - iter2 // 两个迭代器相减的结果是它们之间的距离
>, >=, <, <= // 位置比较
数组
多维数组
for(auto &row : a)
for (auto &col : row){
col = cnt;
++cnt;
}
int (*ip)[4]; // 指向含有4个整数的数组
术语
4.1 基础
4.2 算术运算符
4.3 逻辑和关系运算符
4.4 赋值运算符
if (i == j)
4.5 递增和递减运算符
4.6 成员访问运算符
n = p->size();
4.7 条件运算符
4.8 位运算符
4.9 sizeof运算符
sizeof expr
4.10 逗号运算符
4.11 类型转换
// cast-name是static_cast,dynamic_cast,const_cast,reinterpret_cast
4.12 运算符优先级表
5.2 语句作用域
5.3 条件语句
5.4 迭代语句
statement
statement
statement
statement
while (condition)
5.5 跳转语句
5.6 try语句块和异常处理
6.1 函数基础
{
static size_t ctr = 0;
return ++ctr;
}
6.2 参数传递
void pring(const int[]);
void print(const int[10]);
// 以上三个函数等价
int (*matrix)[10]; // 指向含有10个整数的数组的指针
6.3 返回类型和return语句
return expression;
6.4 函数重载
6.5 特殊用途语言特性
string screen(sz ht = 24, sz wid = 80, char background = ' ');
6.6 函数匹配
6.7 函数指针
等价于
void useBigger (const string &s1, const string &s2, bool (*pf)(const string &, const string &));
7.1 定义抽象数据类型
if (units_sol)
return revenue/units_sols;
else
return 0;
}
定义:类通过一个或几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数。 构造函数没有返回类型; 构造函数的名字和类名相同。
7.2 访问控制与封装
说明符 | 用途 |
class Sales_data {
friend Sales_data add(const Sales_data&, const Sales_data&);
friend std::ostream &print(std::ostream&, const Sales_data&);
friend std::istream &read(std::istream&, Sales_data&);
}
// nonmember Sales_data interface functions
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::istream&, Sales_data&);
//Sales_data.cpp
Sales_data
add(const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs; // copy data members from lhs into sum
sum.combine(rhs); // add data members from rhs into sum
return sum;
}
// transactions contain ISBN, number of copies sold, and sales price
istream&
read(istream &is, Sales_data &item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream&
print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.avg_price();
return os;
}
7.3 类的其他特性
char ch = myScreen.get();
ch = myScreen.get(0,0);
private:
std::vector<Screen> screens{Screen(24, 80, ' ')};
}
public:
// display overloaded on whether the object is const or not
Screen &display(std::ostream &os)
{ do_display(os); return *this; }
const Screen &display(std::ostream &os) const
{ do_display(os); return *this; }
}
// Window_mgr的成员可以访问Screen类的私有部分
friend class Window_mgr;
}
// Window_mgr::clear必须在Screen类之前被声明
friend void Window_mgr::clear(ScreenIndex);
}
7.4 类的作用域
7.5 构造函数再探
public:
ConstRef (int i);
private:
int i;
const int ci;
int &ri;
};
ConstRef:ConstRef(int ii) : i(ii), ci(ii), ri(i){ }
7.6 类的静态成员
r = Account::rate();
小结
iostream处理控制台IO fstream处理命名文件IO stringstream完成内存string的IO
8.1 IO类
8.2 文件输入输出
类 | 作用 |
8.3 string流
类 | 作用 |
string line, word;
// will hold all the records from the input
vector<PersonInfo> people;
// read the input a line at a time until end-of-file (or other error)
while (getline(is, line)) {
PersonInfo info; // object to hold this record's data
istringstream record(line); // bind record to the line we just read
record >> info.name; // read the name
while (record >> word) // read the phone numbers
info.phones.push_back(word); // and store them
people.push_back(info); // append this record to people
}
for (vector<PersonInfo>::const_iterator entry = people.begin();
entry != people.end(); ++entry) {
ostringstream formatted, badNums; // objects created on each loop
// for each number
for (vector<string>::const_iterator nums = entry->phones.begin();
nums != entry->phones.end(); ++nums) {
if (!valid(*nums)) {
badNums << " " << *nums; // string in badNums
} else
// ``writes'' to formatted's string
formatted << " " << format(*nums);
}
if (badNums.str().empty()) // there were no bad numbers
os << entry->name << " " // print the name
<< formatted.str() << endl; // and reformatted numbers
else // otherwise, print the name and bad numbers
cerr << "input error: " << entry->name
<< " invalid number(s) " << badNums.str() << endl;
}
9.1 顺序容器概述
类型 | 作用 |
9.2 容器库概述
类型别名 | |
构造函数 | |
赋值与swap | |
大小 | |
添加/删除元素(不适用于array) | |
关系运算符 | |
获取迭代器 | |
反向容器的额外成员(不支持forward_list) | |
*begin = val;
++begin;
}
C c1(c2)
C c1=c2
C c{a,b,c...} // 列表初始化
C c={a,b,c...}
C c(b,e) // c初始化为迭代器b和e指定范围中的元素的拷贝
// 只有顺序容器(不包括array)的构造函数才能接受大小参数
C seq(n)
C seq(n,t)
s2={0}; // 错误!
9.3 顺序容器操作
svec.insert(svec.begin(), "Hello!");
在顺序容器中访问元素的操作 | |
顺序容器的删除操作 | |
9.4 vector对象是如何增长的
容器大小管理操作 | |
9.5 额外的string操作
构造string的其他方法 | |
string搜索操作 | |
9.6 容器适配器
1、默认构造函数创建一个空对象 2、接受一个容器的构造函数
栈的操作 | |
queue和priority_queue操作 | |
术语
10.1 概述
10.2 初识泛型算法
10.3 定制操作
标准库算法的谓词分为两类: 1、一元谓词:只接受单一参数。 2、二元谓词:接受两个参数。
{
retrun s1.size() < s2.size();
}
sort(words.begin(), words.end(), isShorter);
// capture list 捕获列表,lambda所在函数中定义的局部变量
// 捕获列表只用于局部非static变量,lambda可以直接使用局部static变量和在它所在函数之外声明的名字
// lambda必须使用尾置返回来指定返回类型
// 调用newCallable时,newCallable会调用callable,并传递给它arg_list中的参数
10.4 再探迭代器
istream-iterator操作 | |
ostream_iterator操作 | |
10.5 泛型算法结构
迭代器类别 | |
10.6 特定容器算法
术语
类型 | 备注 |
11.1 使用关联容器
map<string, size_t> word_count;
string word;
while (cin >> word)
++word_count[word];
for (const auto &w : word_count)
count << w.first << " cccurs " < w.second
<< ((w.second > 1) ? " times" : "time") << endl;
map<string, size_t> word_count;
set<string> exclude = {"the", "But"};
string word;
while (cin >> word)
// 只统计不在exclude中的单词
if (exclude.find(word) == exclude.end())
++word_count[word]; //获取并递增word的计数器
11.2 关联容器概述
pair<string, string> author{"James", "Joyce"}; // 也可为每个成员提供初始化器
11.3 关联容器操作
关联容器额外的类型别名 | |
关联容器insert操作 | |
从关联容器删除元素 | |
map和unorder_map的下标操作 | |
c.count(k) // 返回关键字等于k的元素的数量。对于不允许重复关键字的容器,返回值永远是0或1
c.lower_bound(k) // 返回一个迭代器,指向第一个关键字不小于k的元素;不适用于无序容器
c.upper_bound(k) // 返回一个迭代器,指向第一个关键字大于k的元素;不适用于无序容器
c.equal_bound(k) // 返回一个迭代器pair,表示关键字等于k的元素的范围。如k不存在,pair的两个成员均等于c.end()
11.4 无序容器
SD_multiset bookStore(42, haser, eqOp);
12.1 动态指针与智能指针
智能指针 | 用途 |
int *pi = new int; // pi指向一个动态分配的、未初始化的无名对象
int *pi = new int(1024); // pi指向的对象的值为1024
int *pi1 = new int; // 默认值初始化;*pi1的值未定义
int *pi2 = new int(); // 值初始化为0;*pi2为0
unique_ptr操作 |
weak_ptr 操作 | |
12.2 动态数组
delete [] pa; // pa必须指向一个动态分配的数组或为空
unique_ptr<T []> u(p);
u[i];
auto const p = alloc.allocate(n);
表达式 | 作用 |
术语
13.1 拷贝、赋值与销毁
public :
Foo(); // 默认构造函数
Foo(const Foo&); // 拷贝构造函数
}
public:
~Foo(); // 析构函数,一个类只会有唯一一个析构函数。
}
public:
Sales_data(const Sales_data&) = default;
}
13.2 拷贝控制和资源管理
{
auto newp = new string(*rhs.ps);
delete ps;
ps = newp;
i = rhs.i;
return *this;
}
13.3 交换操作
13.4 拷贝控制示例
13.5 动态内存管理类
13.6 对象移动
{
}
术语
14.1 基本概念
operator+(data1, data2);
// 以上2个调用等价
14.2 输入和输出运算符
{
os << item.isbn() << " " << item.unites_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
{
double price;
is >> item.bookNo >> item.units_sold >> price;
if (is)
item.revenue = items.units_sold * price;
else
item = Sales_data();
return is;
}
14.3 算术和关系运算符
{
return lhs.isbn() == rhs.isbn() &&
lhs.unites_sold == rhs.units_sold &&
lhs.revenue == rhs.revenue;
}
14.4 赋值运算符
14.5 下标运算符
public:
std::string& operator[](std::size_t n){
return elements[n];
}
const std::string& operator[](std::size_t n) const{
return elements[n];
}
private:
std::string *elements;
}
14.6 递减和递增运算符
public:
StrBlobPtr& operator++(); // 前置运算符
StrBlobPtr& operator--();
}
public:
StrBlobPtr operator++(int); // 后置运算符
StrBlobPtr operator--(int);
}
14.7 成员访问运算符
14.8 函数调用运算符
int operator()(int val) const {
return val < 0 ? -val : val;
}
};
absInt absObj;
int ui = absObj(i);
14.9 重载、类型转换与运算符
术语
15.1 OOP:概述
继承是一种类联系在一起的一种层次关系。这种关系中,根部是基类,从基类继承而来的类成为派生类。
public:
std::string isbn() const;
virtual double net_price(std::size_t n) const;
}
15.2 定义基类和派生类
基类将该函数定义为虚函数(virtual)。
基类通过在其成员函数的声明语句之前加上关键词virtual使得该函数执行动态绑定。
关键词virtual只能出现在类内部的声明语句之前而不能用于类外部的函数定义。
如果基类把一个函数声明成虚函数,则该函数在派生类中隐式的也是虚函数。
... // 省略
}
Bulk_quote bulk; // 派生类
Quote *p = &item; // p指向Quote对象
p = &bulk; // p指向bulk的Quote部分
Quote &r = bulk; // r绑定到bulk的Quote部分。
Bulk_quote *bulkP = &base; // 错误!
Bulk_quote *bulkRef = base; // 错误!
15.3 虚函数
15.4 抽象基类
public:
double net_price(std::size_t) const = 0;
}
15.5 访问控制与继承
public:
using Base::size;
}
struct D1 : Base {}; // 默认public继承
class D2 : Base {}; // 默认private继承
15.6 继承中的类作用域
15.7 构造函数与拷贝控制
delete itemP; // 调用Quote的析构函数
itemP = new Bulk_quote;
delete itemP; // 调用Bulk_quote的析构函数
15.8 容器与继承
术语
- EOF -
关注『CPP开发者』
看精选C++技术文章 . 加C++开发者专属圈子
点赞和在看就是最大的支持❤️